<?php

class WeeklyReport {
  
  protected $doc = null;
  

  protected $basic;
  
  protected $issues;
  protected $others;
  protected $followUps;
  protected $plans;
  
  public function __construct($file)
  {
    $content = file_get_contents($file);
    $pos = preg_match('/\\<\\?xml\\s*version="1\\.0".*mso-infoPathSolution.*weekly_report\\.xsn/s', $content, $matches);
    if ($matches == null) {
      throw new Exception('This file is not a weekly report, please try another one');
    }
    $xmlDoc = new DOMDocument();
    $xmlDoc->load($file);
    $this->doc = $xmlDoc;

  }
  
  public function getBasic()
  {
    return array(
      'name'  => trim($this->doc->getElementsByTagName('name')->item(0)->nodeValue), 
      'date1' => trim($this->doc->getElementsByTagName('date')->item(0)->nodeValue), 
      'date2' => trim($this->doc->getElementsByTagName('date1')->item(0)->nodeValue), 
      'hours' => trim($this->doc->getElementsByTagName('hours')->item(0)->nodeValue)
    );
  }
  
  private function getSubNode($tagName, $nameFilter)
  {
    $all_issues = $this->doc->getElementsByTagName($tagName);
    $ret = null;
    foreach ($all_issues as $i => $issue)
    {
      foreach ($issue->childNodes as $item)
      {
        $name = str_replace($nameFilter, '', $item->nodeName);
        if ($name == '#text') continue;
        $ret[$i][$name] = trim($item->nodeValue);
      }
    }
    return $ret;
    
  }
  
  public function getIssues()
  {
    return $this->getSubNode('issue', 'my:issue_');
  }
  
  public function getOthers()
  {
    return $this->getSubNode('others', 'my:item_');
  }
  
  public function getFollowUps()
  {
    return $this->getSubNode('open_issues', 'my:open_issue_');
  }
  
  private function getPlanNode($tagName)
  {
    $plans = $this->doc->getElementsByTagName($tagName);
    $ret = null;
    foreach ($plans as $i => $plan)
    {
      foreach ($plan->childNodes as $item)
      {
        $ret[$i] = trim($item->nodeValue);
      }
    }
    return $ret;
  }
  
  public function getPlans()
  {
    $plans[1]  = $this->getPlanNode('important_urgent');
    $plans[2]  = $this->getPlanNode('important_not_urgent');
    $plans[3]  = $this->getPlanNode('not_important_urgent');
    $plans[4]  = $this->getPlanNode('not_important_not_urgent');
    return $plans;
  }
  
  private function getAll()
  {
    if (!$this->hasData()) {
      $this->basic      = $this->getBasic();
      $this->issues     = $this->getIssues();
      $this->others     = $this->getOthers();
      $this->followUps  = $this->getFollowUps();
      $this->plans      = $this->getPlans();
    }
  }
  
  private function hasData()
  {
    if ($this->basic == null) return 0;
    return 1;
  }
  
  public function isRecordCorrect($name, $date)
  {
    $this->getAll();
    if ($name != $this->basic['name']) return false;
    if (strtotime($date) != strtotime($this->basic['date1'])) return false;
    $dt = new DateTime($date);
    $dt->modify("+4 days");
    if (strtotime($dt->format('Y-m-d')) != strtotime($this->basic['date2'])) return false;
    return true;  
  }
  
  public function isRecordExists()
  {
    $this->getAll();
    
    $c = new Criteria();
    $c->add(WrBasicPeer::MEMBER_ID, WrMemberPeer::getMemberIdByName($this->basic['name']));
    $c->add(WrBasicPeer::DATE1, $this->basic['date1']);
    $c->add(WrBasicPeer::DATE2, $this->basic['date2']);
    $basic = WrBasicPeer::doSelectOne($c);
    if ($basic != null) {
      return 1;
    }
    
    return 0;
  }
  
  public function getNormName()
  {
    return $this->basic['name'].'_'.$this->basic['date1'].'_'.$this->basic['date2'].'.xml';
  }
  
  public function save($name, $member_id, $date)
  {
    $this->getAll();
    
    if (!$this->isRecordCorrect($name, $date)) {
      throw new Exception('This weekly report is for '.
        $this->basic['name']. 
        ' from '.$this->basic['date1'].' to '.$this->basic['date2'].
        " is not equal to your input ${name} and ${date}, please modify it."
      );
    }
    
    if ($this->isRecordExists()) {
      throw new Exception('The weekly report for '.
        $this->basic['name'].
        ' from '.$this->basic['date1'].' to '.$this->basic['date2'].
        ' exists, please submit another one');
    }
    
    $basic = new WrBasic();
    
    $basic->setMemberId($member_id);
    $basic->setDate1($this->basic['date1']);
    $basic->setDate2($this->basic['date2']);
    $basic->setHours($this->basic['hours']);
    
    if (count($this->issues) > 0)
    {
      foreach ($this->issues as $issue)
      {
        $wri = new WrIssue();
        if (trim($issue['category']) == '') continue;
              
        $wri->setIssueId($issue['id']);
        $wri->setCategory($issue['category']);
        $wri->setSynopsis($issue['synopsis']);
        $wri->setComment($issue['comment']);
        $wri->setCompleted($issue['completed']);
        $wri->setHour($issue['hour']);
        $basic->addWrIssue($wri);
      }
    }
    
    if (count($this->others) > 0) 
    {
      foreach($this->others as $other)
      {
        $wro = new WrOthers();
        if (trim($other['category']) == '') continue;
        
        $wro->setCategory($other['category']);
        $wro->setSynopsis($other['synopsis']);
        $wro->setStatus($other['status']);
        $wro->setCompleted(($other['completed']));
        $wro->setHour($other['hour']);
        $basic->addWrOthers($wro);
      }
    }
    
    if (count($this->followUps) > 0)
    {
      foreach ($this->followUps as $followup)
      {
        if (trim($followup['item']) == '') continue;
        $wrf = new WrFollowup();
        $wrf->setSynopsis($followup['item']);
        $basic->addWrFollowup($wrf);
      }
    }
    
    foreach ($this->plans as $category => $plan)
    {
      if (count($plan) > 0) {
        foreach ($plan as $p)
        {
          if (trim($p) == '') continue;
          $wrp = new WrPlan();
          $wrp->setCategory($category);
          $wrp->setSynopsis($p);
          $basic->addWrPlan($wrp);       
        }
      }
    }
    
    $basic->save();
    return 0;
  }
}